// src/main/java/com/nb/service/impl/SysMenuServiceImpl.java
package com.nb.service.impl;

import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.nb.annotation.LogAsync;
import com.nb.entity.SysAclEntity;
import com.nb.entity.SysMenuEntity;
import com.nb.mapper.SysMenuMapper;
import com.nb.service.ISysAclService;
import com.nb.service.ISysMenuService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 菜单表 服务层实现。
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenuEntity> implements ISysMenuService {
    private static final Logger logger = LoggerFactory.getLogger(SysMenuServiceImpl.class);

    @Autowired
    private ISysAclService sysAclService; // 注入acl服务

    /**
     * 校验菜单名称是否唯一
     *
     * @param menu 菜单信息
     * @return 结果
     */
    @Override
    public boolean checkMenuNameUnique(SysMenuEntity menu) {
        QueryWrapper queryWrapper = QueryWrapper.create()
                .select()
                .from("sys_menu")
                .where("name = ?", menu.getName())
                .and("id != ?", menu.getId() != null ? menu.getId() : -1L)
                .and("is_delete = ?", 0);

        return getOne(queryWrapper) == null;
    }

    /**
     * 校验菜单路径是否唯一
     *
     * @param menu 菜单信息
     * @return 结果
     */
    @Override
    public boolean checkMenuPathUnique(SysMenuEntity menu) {
        if (menu.getPath() == null || menu.getPath().isEmpty()) {
            return true;
        }

        QueryWrapper queryWrapper = QueryWrapper.create()
                .select()
                .from("sys_menu")
                .where("path = ?", menu.getPath())
                .and("id != ?", menu.getId() != null ? menu.getId() : -1L)
                .and("is_delete = ?", 0);

        return getOne(queryWrapper) == null;
    }

    /**
     * 创建菜单
     *
     * @param menu 菜单信息
     * @return 结果
     */
    @Override
    @LogAsync("创建菜单")
    @Transactional
    public boolean createMenu(SysMenuEntity menu) {
        logger.info("Creating menu: {}", menu);

        boolean result = save(menu);
        logger.info("Menu creation result: {}, menuId: {}", result, menu.getId());

        if (menu.getAclId() != null) {
            SysAclEntity acl = sysAclService.getById(menu.getAclId());
            // 添加后续处理逻辑
            if (acl != null) {
                logger.info("Associated ACL found: {}", acl);
                // 在这里添加关联处理逻辑
            }
        }

        return result;
    }

    /**
     * 校验菜单是否存在
     *
     * @param menuId 菜单ID
     * @return 结果
     */
    @Override
    public boolean checkMenuExists(Long menuId) {
        if (menuId == null) {
            return false;
        }

        QueryWrapper queryWrapper = QueryWrapper.create()
                .select()
                .from("sys_menu")
                .where("id = ?", menuId)
                .and("is_delete = ?", 0);

        return getOne(queryWrapper) != null;
    }

    /**
     * 更新菜单
     *
     * @param menu 菜单信息
     * @return 结果
     */
    @Override
    @LogAsync("更新菜单")
    public boolean updateMenu(SysMenuEntity menu) {
        logger.info("Updating menu: {}", menu);

        // 检查菜单是否存在
        if (!checkMenuExists(menu.getId())) {
            logger.warn("Menu not found, menuId: {}", menu.getId());
            return false;
        }

        // 更新菜单信息
        boolean result = updateById(menu);
        logger.info("Menu update result: {}, menuId: {}", result, menu.getId());

        // 处理权限关联更新
        if (menu.getAclId() != null) {
            SysAclEntity acl = sysAclService.getById(menu.getAclId());
            if (acl != null) {
                logger.info("Associated ACL found for update: {}", acl);
                // 在这里添加关联处理逻辑
            }
        }
        return result;
    }

    /**
     * 检查是否存在子菜单
     *
     * @param menuId 菜单ID
     * @return 结果
     */
    @Override
    public boolean hasChildMenus(Long menuId) {
        if (menuId == null) {
            return false;
        }

        QueryWrapper queryWrapper = QueryWrapper.create()
                .select()
                .from("sys_menu")
                .where("parent_id = ?", menuId)
                .and("is_delete = ?", 0);

        return getOne(queryWrapper) != null;
    }

    /**
     * 删除菜单
     *
     * @param menuId 菜单ID
     * @return 结果
     */
    @Override
    @LogAsync("删除菜单")
    public boolean deleteMenu(Long menuId) {
        logger.info("Deleting menu, menuId: {}", menuId);

        // 检查菜单是否存在
        if (!checkMenuExists(menuId)) {
            logger.warn("Menu not found, menuId: {}", menuId);
            return false;
        }

        // 禁止删除系统核心菜单（如首页）
        SysMenuEntity menu = getById(menuId);
        if ("首页".equals(menu.getName())) {
            logger.warn("Cannot delete system core menu, menuId: {}", menuId);
            return false;
        }

        // 检查是否存在子菜单
        if (hasChildMenus(menuId)) {
            logger.warn("Menu has child menus, cannot delete, menuId: {}", menuId);
            return false;
        }

        // 标记为删除状态 (逻辑删除)
        SysMenuEntity menuToUpdate = new SysMenuEntity();
        menuToUpdate.setId(menuId);
        menuToUpdate.setIsDelete(1);


        boolean result = updateById(menuToUpdate);
        logger.info("Menu delete result: {}, menuId: {}", result, menuId);

        // 解除权限点关联
        if (menu.getAclId() != null) {
            // 更新菜单的acl_id为null，解除关联
            SysMenuEntity menuToUnlink = new SysMenuEntity();
            menuToUnlink.setId(menuId);
            menuToUnlink.setAclId(null);

            // 如果删除操作成功，则更新菜单解除权限关联
            if (result) {
                updateById(menuToUnlink);
                logger.info("Unlinked ACL association for menuId: {}, aclId: {}", menuId, menu.getAclId());
            }
        }
        return result;
    }
    @Override
    public Page<SysMenuEntity> selectMenuPage(int page, int size, String name, String path){
        logger.info("Selecting menu page, page: {}, size: {}, name: {}, path: {}", page, size, name, path);
        Page<SysMenuEntity> pageObj = new Page<>(page, size);
        QueryWrapper queryWrapper = QueryWrapper.create()
                .select()
                .from("sys_menu")
                .where("is_delete = ?", 0);
        // 菜单名称模糊查询
        if (name != null && !name.isEmpty()) {
            queryWrapper.and("name like ?", "%" + name + "%");
        }

        // 路由路径精确查询
        if (path != null && !path.isEmpty()) {
            queryWrapper.and("path = ?", path);
        }
        // 按照排序字段和ID排序
        queryWrapper.orderBy("sort ASC, id ASC");

        // 执行分页查询
        Page<SysMenuEntity> result = page(pageObj, queryWrapper);
        logger.info("Menu page query result, total: {}", result.getTotalRow());

        return result;
    }
    /**
     * 根据菜单ID查询菜单详情
     * @param menuId 菜单ID
     * @return 菜单详情
     */
    @Override
    public SysMenuEntity selectMenuById(Long menuId) {
        logger.info("Selecting menu by id: {}", menuId);

        if (menuId == null) {
            logger.warn("Menu id is null");
            return null;
        }

        // 查询未被删除的菜单
        QueryWrapper queryWrapper = QueryWrapper.create()
                .select()
                .from("sys_menu")
                .where("id = ?", menuId)
                .and("is_delete = ?", 0);

        SysMenuEntity menu = getOne(queryWrapper);
        logger.info("Menu detail query result: {}", menu != null ? "found" : "not found");

        return menu;
    }
    @Override
    @LogAsync("更新菜单排序和父菜单")
    public boolean updateMenuSortAndParent(Long menuId, Long parentId, Integer sort) {
        logger.info("Updating menu sort and parent, menuId: {}, parentId: {}, sort: {}", menuId, parentId, sort);

        // 校验菜单是否存在
        if (!checkMenuExists(menuId)) {
            logger.warn("Menu not found, menuId: {}", menuId);
            return false;
        }

        // 校验父菜单是否存在（如果提供了父菜单ID）
        if (parentId != null && parentId > 0 && !checkMenuExists(parentId)) {
            logger.warn("Parent menu not found, parentId: {}", parentId);
            return false;
        }

        // 不能将菜单设置为自己的父菜单
        if (menuId.equals(parentId)) {
            logger.warn("Cannot set menu as its own parent, menuId: {}", menuId);
            return false;
        }

        // 检查是否存在循环引用（父菜单不能是当前菜单的子菜单）
        if (parentId != null && parentId > 0 && isChildOf(parentId, menuId)) {
            logger.warn("Cannot set child menu as parent, would create circular reference, menuId: {}, parentId: {}", menuId, parentId);
            return false;
        }

        // 更新菜单排序和父菜单
        SysMenuEntity menuToUpdate = new SysMenuEntity();
        menuToUpdate.setId(menuId);
        menuToUpdate.setParentId(parentId);
        menuToUpdate.setSort(sort);

        boolean result = updateById(menuToUpdate);
        logger.info("Menu sort and parent update result: {}, menuId: {}", result, menuId);

        // TODO: 刷新菜单树缓存（如果实现了缓存机制）
        // refreshMenuTreeCache();

        return result;
    }

    /**
     * 检查一个菜单是否是另一个菜单的子菜单（递归检查）
     * @param childId 可能的子菜单ID
     * @param parentId 可能的父菜单ID
     * @return 是否是子菜单
     */
    private boolean isChildOf(Long childId, Long parentId) {
        if (childId == null || parentId == null) {
            return false;
        }

        // 查询childId的父菜单
        SysMenuEntity childMenu = getById(childId);
        if (childMenu == null || childMenu.getParentId() == null) {
            return false;
        }

        // 如果直接父菜单就是目标父菜单
        if (childMenu.getParentId().equals(parentId)) {
            return true;
        }

        // 递归检查上层父菜单
        return isChildOf(childMenu.getParentId(), parentId);
    }

}
